#!/usr/bin/python

#-------------------------------------------------------------------------------
# Name:        serverautocontrol
# Purpose:     To automatically launch, recover, and stop most servers.
#
# Author:      Donald L Talbert , www.bwhgaming.com
#
# Created:     20/09/2012
# Copyright:   (c) Donald L Talbert 2012
# Licence:     MIT
#-------------------------------------------------------------------------------


import subprocess
import shlex
import time
import datetime
import sys
import ConfigParser
import threading
import logging
import os.path

import loadconfig


class ServerAutoControl(object):
    """
	This is the main module to launch, restart, stop, and keep servers
	online.
	"""
    def __init__(self, serverNum, eServerThreadStop, eServerThreadRestarts):
        """
        The class requires 3 args. serverNum is the server number.
        eServerThreadStop stops all servers, eServerThreadRestarts
        stops all servers from restarting.
        """
        # Config File Class Variables
        self.lc = loadconfig.LoadConfig()
        self.restartTime = self.lc.restartTime # Restart time set
        self.listServPaths = self.lc.listServPaths # Paths of all servers.
        self.serverDirectory = self.lc.serverDirectory # Server Dir

        # Function return class varables
        self.serverNum = int(serverNum) - 1 # Current server number to launch
        self.command = shlex.split(self.listServPaths[self.serverNum]) # The command to launch the server

        self.__proc = None

		# events being held in the class.
        self.eServerThreadStop = eServerThreadStop
        self.eServerThreadRestarts = eServerThreadRestarts


    def MainLoop(self):
        """
        This loop checks if the server is online before starting. Then
        it checks the time if its time to restart. Then it checks if any
        stop events have been issued and finally checks if the server has
        been knocked off line via crash or other and restarts it.

        """
        while self.__proc.poll() is None: # Check if server is running then continue.
            self.eServerThreadRestarts.wait() # Waits for HaltRestarts event to be true.
            time.sleep(1)

            # Check Time for daily restart.
            if self.ChkTime() == True:
                self.Restart()
                return None

            # Check if stop event has been issued and stop servers.
            if self.eServerThreadStop.isSet() == True:
                self.Stop()
                return None

            # Check if server is not running. If true it restarts the server.
        if self.__proc.poll() is not None:
            logging.warning("Server Crashed.")
            self.Launch()

        return True

    def Stop(self):
        """
        Stops the server via subprocess method. Used with restarting and
        to stop the servers for time and manually.

        """
        logging.debug("stopping server")
        self.__proc.terminate() # Stops server
        return True

    def Launch(self):
        """
        Launches the server and enters the mainLoop.

        """
        print self.command
        self.__proc = subprocess.Popen(self.command) #Launches server.
        self.MainLoop()
        return True

    def Restart(self):
        """
        This method is a simple restart server method.

        """
        logging.info("Servers Restarting.")
        self.Stop() # Stops server
        time.sleep(3)
        self.Launch() # Relaunches server
        return True

    def ChkTime(self):
        """
        This checks the time to see if its ready to restart the servers.
        it does not restart but returns a bool to be used to judge if the
        servers should be restarted.

        """
        now = datetime.datetime.now()
        now_time = now.time()

        # Setting time a1 a2 is 4:15 and a1,a3 is 4:16 by default
        a1 = int(self.restartTime[0])
        a2 = int(self.restartTime[1])
        a3 = a2 + 1

        if now_time >= datetime.time(a1,a2) and now_time <= datetime.time(a1,a3): #change to 4,15 , 4,16
            time.sleep(64)
            return True
        else:
            return False


if __name__ == '__main__':
    pass
